package cn.mw.cmdb.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.mw.cmdb.entity.*;
import cn.mw.cmdb.param.*;
import cn.mw.cmdb.param.zabbixResult.*;
import cn.mw.cmdb.service.ServiceAction;
import cn.mw.cmdb.service.impl.CmdbServiceManage;
import cn.mw.cmdb.service.impl.InstanceMonitorServiceImpl;
import cn.mw.cmdb.service.impl.InstanceServiceImpl;
import cn.mw.cmdb.template.enums.TemplateDetailEnum;
import cn.mw.cmdb.template.param.MwTemplateConfigurationParam;
import cn.mw.cmdb.template.service.MwTemplateConfigurationService;
import cn.mw.cmdb.template.service.impl.MwTemplateConfigurationServiceImpl;
import cn.mw.cmdb.virtualization.param.VirtualizationParam;
import cn.mw.cmdb.virtualization.service.MwVirtualizationService;
import cn.mw.components.mongodb.page.MWPage;
import cn.mw.microMonitorCommon.api.common.BaseApiService;
import cn.mw.microMonitorCommon.api.common.ResponseBase;
import cn.mw.microMonitorCommon.constants.ZabbixItemConstant;
import cn.mw.microMonitorCommon.util.SpringUtils;
import com.google.common.base.Strings;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static cn.mw.cmdb.service.impl.InstanceMonitorServiceImpl.overview;

@RequestMapping("/instanceMonitor")
@Controller
@Tag(name = "资产监控")
@Slf4j
public class InstanceMonitorController extends BaseApiService {
    private CmdbServiceManage cmdbServiceManage;

    private MessageSource messageSource;
    private MwVirtualizationService mwVirtualizationService;

    private MwTemplateConfigurationService mwTemplateConfigurationService;

    public InstanceMonitorController(CmdbServiceManage cmdbServiceManage
            , MessageSource messageSource, MwVirtualizationService mwVirtualizationService) {
        this.cmdbServiceManage = cmdbServiceManage;
        this.messageSource = messageSource;
        this.mwVirtualizationService = mwVirtualizationService;
    }

    @PostMapping("/addLayout")
    @ResponseBody
    @Operation(summary = "新增布局")
    public ResponseBase createLayout(@RequestBody MwTabLayoutInfo params) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        service.addLayoutDataTabTest(params);
        return setResultSuccess(messageSource.getMessage("add-success", null, LocaleContextHolder.getLocale()));
    }

    @PostMapping("/queryLayoutTabList")
    @ResponseBody
    @Operation(summary = "查询布局的tab页信息")
    public ResponseBase queryLayoutTabList(@RequestBody MwComponentLayoutInfo param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        List<MwLayoutLabelInfo> mwLayoutLabelInfos = service.queryLayoutTabList(param);
        return setResultSuccess(mwLayoutLabelInfos);
    }

    @PostMapping("/queryLayoutByTabId")
    @ResponseBody
    @Operation(summary = "根据tabId查询布局信息")
    public ResponseBase queryLayoutByTabId(@RequestBody MwTabLayoutInfo param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        MwTabLayoutInfo mwTabLayoutInfo = service.queryLayoutByTabId(param);
        return setResultSuccess(mwTabLayoutInfo);
    }

    @PostMapping("/getInstanceBaseInfo")
    @ResponseBody
    @Operation(summary = "获取资产的基础信息")
    public ResponseBase getInstanceBaseInfo(@RequestBody QueryMonitorParam param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        MwInstanceBaseMonitorInfo instanceBaseInfo = service.getInstanceBaseInfo(param);
        return setResultSuccess(instanceBaseInfo);
    }

    @PostMapping("/getAvailableInfo")
    @ResponseBody
    @Operation(summary = "获取基础可用性信息")
    public ResponseBase getAvailableInfo(@RequestBody MwMonitorHistoryParam param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        AvailableInfoDTO availableInfo = service.getAvailableInfo(param);
        return setResultSuccess(availableInfo);
    }


    @PostMapping("/getDefaultTabInfo")
    @ResponseBody
    @Operation(summary = "获取默认固定tab信息")
    public ResponseBase getDefaultTabInfo() throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        List<MwLayoutLabelInfo> defaultTabInfo = service.getDefaultTabInfo();
        return setResultSuccess(defaultTabInfo);
    }

    @PostMapping("/addTabInfo")
    @ResponseBody
    @Operation(summary = "新增tab标签信息")
    public ResponseBase addTabInfo(@RequestBody MwLayoutLabelInfo param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        service.addTabInfo(param);
        return setResultSuccess(messageSource.getMessage("add-success", null, LocaleContextHolder.getLocale()));
    }

    @PostMapping("/updateTabInfo")
    @ResponseBody
    @Operation(summary = "修改tab标签信息")
    public ResponseBase updateTabInfo(@RequestBody MwLayoutLabelInfo param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        service.updateTabInfo(param);
        return setResultSuccess(messageSource.getMessage("upd-success", null, LocaleContextHolder.getLocale()));
    }

    @PostMapping("/deleteTabInfo")
    @ResponseBody
    @Operation(summary = "删除tab标签信息")
    public ResponseBase deleteTabInfo(@RequestBody MwLayoutLabelInfo param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        service.deleteTabInfo(param);
        return setResultSuccess(messageSource.getMessage("del-success", null, LocaleContextHolder.getLocale()));
    }

    @PostMapping("/initMonitorParam")
    @ResponseBody
    @Operation(summary = "初始化监控查询参数")
    public ResponseBase initMonitorParam(@RequestBody QueryMonitorParam param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        QueryMonitorParam queryMonitorParam = service.initMonitorParam(param.getInstanceId());
        InitMonitorParam initMonitorParam = new InitMonitorParam();
        BeanUtil.copyProperties(queryMonitorParam, initMonitorParam, CopyOptions.create().setIgnoreNullValue(true));
        String hostId = queryMonitorParam.getHostId();
        if (queryMonitorParam.getMonitorServerId() != null && queryMonitorParam.getMonitorServerId().intValue() != 0 && (!Strings.isNullOrEmpty(hostId) && !"0".equals(hostId))) {
            MwComponentLayoutInfo layoutInfo = service.getLayoutInfo(queryMonitorParam);
            List<String> overViewIds = layoutInfo.getLabels().stream().filter(s -> overview.equals(s.getName())).map(s -> s.getId()).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(overViewIds)) {
                String overViewId = overViewIds.get(0);
                initMonitorParam.setOverViewId(overViewId);
            }
        }
        return setResultSuccess(initMonitorParam);
    }


    @PostMapping("/queryItemInfoList")
    @ResponseBody
    @Operation(summary = "查询筛选后的监控项集合")
    public ResponseBase queryItemInfoList(@RequestBody QueryArgumentsParam param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        List<ItemApplication> itemApplications = service.queryItemInfoList(param);
        return setResultSuccess(itemApplications);
    }

    @PostMapping("/getApplicationList")
    @ResponseBody
    @Operation(summary = "高级表格查询所有应用集list")
    public ResponseBase getApplicationList(@RequestBody QueryArgumentsParam param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        List<MwZabbixApplicationResultParam> itemApplications = service.getApplicationList(param);
        return setResultSuccess(itemApplications);
    }

    @PostMapping("/getItemListByApplication")
    @ResponseBody
    @Operation(summary = "高级表格根据应用集查询监控项和监控设备list")
    public ResponseBase getItemListByApplication(@RequestBody MwZabbixApplicationResultParam param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        AdvanceTableItemParam itemApplications = service.getItemListByApplication(param);
        return setResultSuccess(itemApplications);
    }

    @PostMapping("/getItemNameMapper")
    @ResponseBody
    @Operation(summary = "查询监控指标映射名称")
    public ResponseBase getItemNameMapper(@RequestBody ItemNameMapperInfo param) throws Exception {
        List list = (List) cmdbServiceManage.service(param, ServiceAction.list);
        return setResultSuccess(list);
    }

    @PostMapping("/updateItemNameMapper")
    @ResponseBody
    @Operation(summary = "修改监控指标数据")
    public ResponseBase updateItemNameMapper(@RequestBody ItemNameMapperInfo param) throws Exception {
        cmdbServiceManage.service(param, ServiceAction.update);
        return setResultSuccess(messageSource.getMessage("upd-success", null, LocaleContextHolder.getLocale()));
    }


    @PostMapping("/getMonitorHistoryInfo")
    @ResponseBody
    @Operation(summary = "获取监控历史数据")
    public ResponseBase getMonitorHistoryInfo(@RequestBody MwMonitorHistoryParam param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        Object obj = service.getMonitorHistoryInfo(param);
        return setResultSuccess(obj);
    }

    @PostMapping("/getAllApplicationList")
    @ResponseBody
    @Operation(summary = "监控指标获取应用集列表")
    public ResponseBase getAllApplicationList(@RequestBody MwMonitorHistoryParam param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        Object obj = service.getAllApplicationList(param);
        return setResultSuccess(obj);
    }

    @PostMapping("/getItemInfoByApplication")
    @ResponseBody
    @Operation(summary = "监控指标根据应用集获取监控数据")
    public ResponseBase getItemInfoByApplication(@RequestBody MwQueryApplicationParam param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        Object obj = service.getItemInfoByApplication(param);
        return setResultSuccess(obj);
    }

    @PostMapping("/itemCheckNowByIds")
    @ResponseBody
    @Operation(summary = "监控指标立即刷新")
    public ResponseBase itemCheckNowByIds(@RequestBody QueryMonitorParam param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        boolean obj = service.itemCheckNow(param);
        if (!obj) {
            setResultFail();
        }
        return setResultSuccess();
    }


    @PostMapping("/getAllMonitorInstanceInfos")
    @ResponseBody
    @Operation(summary = "获取所有纳管的资产信息")
    public ResponseBase getAllMonitorInstanceInfos() throws Exception {
        InstanceServiceImpl service = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        InstanceSearchParam instanceSearchParam = new InstanceSearchParam();
        instanceSearchParam.setIgnoreDataAuth(true);
        List<InstanceInfoExtend> list = service.getAllMonitorInstanceList(instanceSearchParam);
        List<InstanceInfoCustomParam> instanceInfoCustomParams = BeanUtil.copyToList(list, InstanceInfoCustomParam.class);
        return setResultSuccess(instanceInfoCustomParams);
    }


    @PostMapping("/getItemInfosByInstanceId")
    @ResponseBody
    @Operation(summary = "获取资产对应的全部监控指标名称")
    public ResponseBase getAllItemsByInstanceId(@RequestBody MwQueryApplicationParam param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        QueryMonitorParam queryMonitorParam = service.initMonitorParam(param.getInstanceId());
        BeanUtil.copyProperties(queryMonitorParam, param, CopyOptions.create().setIgnoreNullValue(true));
        param.setApplicationName(ZabbixItemConstant.APPLICATION_NAME);
        param.setPage(new MWPage(1, 10000000));
        Object obj = service.getItemInfoByApplication(param);
        List<MwCommonItemInfo> allItemInfos = new ArrayList<>();
        if (obj != null && obj instanceof MWPage) {
            MWPage mwPage = (MWPage) obj;
            allItemInfos = BeanUtil.copyToList(mwPage.getRecords(), MwCommonItemInfo.class);
        }
        return setResultSuccess(allItemInfos);
    }

    @PostMapping("/getTriggerInfoByInstanceId")
    @ResponseBody
    @Operation(summary = "获取资产对应的触发器数据")
    public ResponseBase getTriggerInfoByInstanceId(@RequestBody MwQueryApplicationParam param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        QueryMonitorParam queryMonitorParam = service.initMonitorParam(param.getInstanceId());
        MwTemplateConfigurationParam triggerParam = new MwTemplateConfigurationParam();
        triggerParam.setHostId(queryMonitorParam.getHostId());
        triggerParam.setServerId(queryMonitorParam.getMonitorServerId());
        triggerParam.setDetailType(TemplateDetailEnum.TRIGGERS.getType());
        triggerParam.setPage(new MWPage(1, 10000000));
        MwTemplateConfigurationServiceImpl bean = SpringUtils.getBean(MwTemplateConfigurationServiceImpl.class);
        Object templateDetailInfo = bean.getTemplateDetailInfo(triggerParam);
        return setResultSuccess(templateDetailInfo);
    }

    @PostMapping("/getItemInfos")
    @ResponseBody
    @Operation(summary = "监控指标查询")
    public ResponseBase queryItemInfos(@RequestBody QueryItemInfoListParam param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        QueryMonitorParam queryMonitorParam = service.initMonitorParam(param.getInstanceId());
        BeanUtil.copyProperties(queryMonitorParam, param, CopyOptions.create().setIgnoreNullValue(true));
        List<MwCommonItemInfo> list = service.queryItemInfos(param);
        return setResultSuccess(list);
    }

    @PostMapping("/syncDataByEngineId")
    @ResponseBody
    @Operation(summary = "根据引擎元获取同步数据")
    public ResponseBase syncDataByEngineId(@RequestBody VirtualizationParam param) throws Exception {
        mwVirtualizationService.instanceRelationData(param);
        return setResultSuccess();
    }

    @PostMapping("/resettingMonitorItemInfo")
    @ResponseBody
    @Operation(summary = "资产监控数据重置")
    public ResponseBase resettingMonitorItemInfo(@RequestBody QueryMonitorParam param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        service.resettingMonitorItemInfo(param);
        return setResultSuccess();
    }

    @PostMapping("/resettingAllMonitorItemInfo")
    @ResponseBody
    @Operation(summary = "所有资产监控数据全部重置")
    public ResponseBase resettingAllMonitorItemInfo() throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        service.resettingAllMonitorItemInfo();
        return setResultSuccess();
    }


    @PostMapping("/initOverViewLayout")
    @ResponseBody
    @Operation(summary = "初始化概览页监控数据")
    public ResponseBase initOverViewLayout(@RequestBody QueryMonitorParam param) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        service.initOverViewLayout(param.getInstanceId());
        return setResultSuccess();
    }

    @PostMapping("/importMonitorLayout")
    @ResponseBody
    @Operation(summary = "导入监控模板数据")
    public ResponseBase importMonitorLayout(@RequestBody MultipartFile file, HttpServletResponse response) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        service.importMonitorLayout(file, response);
        return setResultSuccess();
    }

    @PostMapping("/exportMonitorLayout")
    @ResponseBody
    @Operation(summary = "导出监控模板数据")
    public ResponseBase exportMonitorLayout(@RequestBody ComponentLayoutInfoExcelExportParam param, HttpServletResponse response) throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        service.exportMonitorLayout(param.getModelGroupId(), response);
        return setResultSuccess();
    }


    @PostMapping("/monitorLayoutConvert")
    @ResponseBody
    @Operation(summary = "监控数据转换初始化")
    public ResponseBase monitorLayoutConvert() throws Exception {
        InstanceMonitorServiceImpl service = (InstanceMonitorServiceImpl) cmdbServiceManage.getModelService(InstanceMonitorServiceImpl.ID);
        service.monitorLayoutConvert();
        return setResultSuccess();
    }
}
